home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / HPXL / MessageRoutines.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  18.2 KB  |  633 lines  |  [TEXT/MPS ]

  1. /* ==========================================================================================
  2.  
  3.     C FILE:            MessageRoutines.c
  4.  
  5.     COPYRIGHT:        (c) 1992-1994 Apple Computer Inc.
  6.                         All rights reserved.
  7.  
  8.     PURPOSE:        This file contains routines which the HPXL driver uses to override
  9.                     some of the universal and vector specific messages.  The file is partitioned
  10.                     into a section for utitlity routines, universal message override routines,
  11.                     and vector specific, message override routines.
  12.                         
  13.     HISTORY:            Date            By            Description
  14.                         -----            ---            ----------------------------------
  15.                         1/20/92            Harita        Initial release
  16.                          12/20/93            dmh            Sync'd up for GX 1.0b3.
  17.                         8/28/94            dmh            Sync'd up for GX 1.0.1.
  18.  
  19. ========================================================================================== */
  20.  
  21. #include <stdio.h>
  22. #include <Types.h>
  23. #include <OSUtils.h>
  24. #include <Memory.h>
  25. #include <ToolUtils.h>
  26. #include <Errors.h>
  27. #include <FixMath.h>
  28.  
  29. #include <graphics types.h>
  30. #include <graphics errors.h>
  31. #include <graphics routines.h>
  32. #include <math routines.h>
  33.  
  34. #include <Messages.h>
  35. #include <PrintingManager.h>
  36. #include <PrintingDrivers.h>
  37. #include <PrintingMessages.h>
  38.  
  39. #include "ResourceDefines.h"
  40. #include "GlobalsDefs.h"
  41. #include "PackageRoutines.h"
  42.  
  43. extern long A5Size (void);
  44. extern void A5Init (void *);
  45.  
  46.  
  47. SpecDrvrGlobals        gGlobals;
  48.  
  49.  
  50. /* ============================ UNIVERSAL MESSAGE OVERRIDE ROUTINES ============================ */
  51.  
  52. /* ======= SD_Initialize =======
  53.  
  54.     The Initalize message is issued when a client uses the NewJob function to create a
  55.     new message chain to perform a job-oriented task.  SD_Initialize initializes
  56.     the globals of the HPGL driver.
  57. */
  58. OSErr SD_Initialize(void)    //    (in)    not used on entry; this routine allocates the handle
  59. {
  60.  
  61.     OSErr        anErr = noErr;
  62.     
  63.     anErr = NewMessageGlobals(A5Size(), A5Init);
  64.     /* initialize globals */
  65.     gGlobals.penWidth = 0;
  66.  
  67.     return(anErr);
  68.     
  69. }
  70. /* SD_Initialize */
  71.  
  72.  
  73. /* ======= SD_ShutDown =======
  74.  
  75.     The ShutDown message is issued after the completion of a job oriented task and the 
  76.     message chain is being destroyed.  SD_ShutDown deallocates the HPXL drivers globals.
  77. */
  78. OSErr SD_ShutDown(void)    
  79. {
  80.     /* dispose off globals */    
  81.     DisposeMessageGlobals();    
  82.     return(noErr);
  83. }
  84. /* SD_ShutDown */
  85.  
  86.  
  87. /* ======= SD_DefaultPrinter =======
  88.  
  89.     The DefaultPrinter message is issued when NewJob is called to create a new default printer
  90.     object for some job.  SD_DefaultPrinter creates a new ViewDevice which represents
  91.     the specific features of the target device (e.g. color info., number of pens, etc.).  It
  92.     attaches the new ViewDevice to the job.  The new ViewDevice is added so that the client
  93.     application can determine specific settings about the device (e.g. in case it wants to constrain
  94.     choices the user can make).
  95. */
  96. OSErr SD_DefaultPrinter(        //    (out)    error code
  97.     gxPrinter         thePrinter) //    (in)    reference to the printer object being defaulted
  98. {
  99.     
  100.     OSErr                anErr = noErr;
  101.     gxViewDevice        vd;
  102.     gxGraphicsError        stickyErr;
  103.     
  104.     /* Allow the other view devices to be set up before we add ours */
  105.     anErr = Forward_GXDefaultPrinter(thePrinter);
  106.     if (anErr != noErr) 
  107.         return(anErr);
  108.     
  109.     /* Create a new view device to represent the characteristics of the plotter. To do this */
  110.     /* we need to create a fake bitmap. */
  111.     {
  112.         gxShape        tempBitmap;
  113.         gxBitmap    aBitmap;
  114.         
  115.         aBitmap.pixelSize        = 1;
  116.         aBitmap.rowBytes        = 0;
  117.         aBitmap.width            = 0;
  118.         aBitmap.height            = 0;
  119.         aBitmap.image            = (char*)gxMissingImagePointer;
  120.         aBitmap.space            = gxNoSpace;
  121.         aBitmap.set                = nil;
  122.         aBitmap.profile            = nil;
  123.         
  124.         tempBitmap = GXNewBitmap(&aBitmap, nil);
  125.         if (tempBitmap == nil)
  126.            return(GXGetGraphicsError(&stickyErr));
  127.         
  128.         vd = GXNewViewDevice(gxScreenViewDevices, tempBitmap);
  129.         GXDisposeShape(tempBitmap);
  130.  
  131.         if (vd == nil)
  132.            return(GXGetGraphicsError(&stickyErr));
  133.     }
  134.     
  135.     /* Set the View Device Mapping to be identity -- render at 72 dpi */
  136.     {
  137.         gxMapping        vdMapping;
  138.         
  139.         ResetMapping(&vdMapping);
  140.         GXSetViewDeviceMapping(vd, &vdMapping);
  141.     }
  142.         
  143.     /* Add the view device to the printer object */
  144.     anErr = GXAddPrinterViewDevice(thePrinter, vd);
  145.     if (anErr != noErr) goto CantAddPrinterVD;
  146.     
  147.     return(anErr);
  148.     
  149. /******* Cleanup *******/
  150.  
  151. CantAddPrinterVD:
  152.  
  153.     GXDisposeViewDevice(vd);
  154.     return(anErr);
  155.  
  156. }
  157. /* SD_DefaultPrinter */
  158.  
  159.  
  160. /* ======= SD_StartSendPage =======
  161.  
  162.     The StartSendPage message is issued when ImagePage is getting ready to render the next document
  163.     page.  SD_StartSendPage uses this signal to do three functions: 1) change the device transformation
  164.     of the Vector IE will use so that Graphics coordinates are properly mapped to plotter coordinates;
  165.     2) check to see if it's a manual feed job, and if so, prompt the user to place the next
  166.     sheet of paper in the printer; otherwise, issue a command to advance the paper; and 3) send an 
  167.     initialization command to the plotter.
  168. */
  169. OSErr SD_StartSendPage(        //    (out)    error code
  170.     gxFormat         pageFormat)    //    (in)    format of the page we will print
  171. {
  172.  
  173.     OSErr                    anErr = noErr;
  174.     gxGraphicsError            stickyErr;
  175.     gxVectorImageDataHdl    hImageData;
  176.     gxTrayFeedInfo            trayFeedInfo;
  177.     long                    itemSize = sizeof(trayFeedInfo);
  178.     
  179.     
  180.     /* First make sure all pending I/O has completed so that everything prints on the current page. */
  181.     anErr = Send_GXWriteData(nil, 0);
  182.     if (anErr != noErr) return (anErr);
  183.  
  184.     /* Next, change the device transformation so IE will translate the page's coordinates properly */
  185.     {
  186.         gxTransform                theTransform;
  187.         gxMapping                    theMapping;
  188.         
  189.         hImageData = gGlobals.hImageData;
  190.         
  191.         /* If a current device transform exists, kill it now */
  192.         if ((*hImageData)->devTransform != nil)
  193.         {
  194.             GXDisposeTransform((*hImageData)->devTransform);
  195.             (*hImageData)->devTransform = nil;
  196.         }
  197.  
  198.         ResetMapping(&theMapping);
  199.         
  200.         /* This mapping causes the coordinates (x,y) to flip so they become (y,x) */
  201.         theMapping.map[0][0] = 0x00000000;
  202.         theMapping.map[1][1] = 0x00000000;
  203.         theMapping.map[0][1] = 0x00010000;
  204.         theMapping.map[1][0] = 0x00010000;
  205.     
  206.         theTransform = GXNewTransform();
  207.         if (theTransform == nil)
  208.           return(GXGetGraphicsError(&stickyErr));
  209.         
  210.         GXSetTransformMapping(theTransform, &theMapping);
  211.         (*hImageData)->devTransform = theTransform;
  212.     }
  213.     
  214.     /* Now check to see if it's a manual feed page. If so, display a dialog prompting the user to */
  215.     /* place paper into the plotter; otherwise, issue a command to the device to feed the paper. */
  216.  
  217.     anErr = GetCollectionItem (GXGetJobCollection( GXGetJob() ),
  218.                                  gxTrayFeedTag,
  219.                                  gxPrintingTagID,
  220.                                  &itemSize,
  221.                                  &trayFeedInfo );
  222.             
  223.     if (trayFeedInfo.manualFeedThisPage)    // T --> manual feed job;
  224.         {
  225.             gxStatusRecord        *pStatus;
  226.  
  227.             pStatus = (gxStatusRecord*) NewPtr( sizeof(gxStatusRecord) + sizeof(short) );
  228.             if (pStatus == nil) 
  229.                 {
  230.                 anErr = MemError();
  231.                 goto CantMakeStatusRecord;
  232.                 }
  233.             
  234.             /* Fill in the status record appropriately */
  235.             pStatus->statusOwner    = 'drvr';
  236.             pStatus->statResId        = kUserAttentionID;
  237.             pStatus->statResIndex    = 1; //kManualFeedStatus;
  238.             pStatus->dialogResult    = nil;
  239.             pStatus->bufferLen        = nil;
  240.             /* Continue alerting the user until he responds */
  241.             do
  242.             {
  243.                 anErr = GXAlertTheUser(pStatus);
  244.                 
  245.                 /* Note that we can't tell when the user places paper in the plotter */
  246.             }
  247.             while ((anErr == noErr) && (pStatus->dialogResult == nil));
  248.     
  249.             /* Examine the user's response to know whether to continue or cancel */
  250.             switch ( *( (short *) (&pStatus->statusBuffer[0])) )
  251.             {
  252.                 case ok:            // Assume the paper is loaded
  253.                     anErr = noErr;
  254.                     break;
  255.                     
  256.                 case cancel:    //    User wants to terminate the job
  257.                     anErr = gxPrUserAbortErr;
  258.                     break;
  259.             }
  260.  
  261.             /* Dump the temporary status record */
  262.             DisposPtr((Ptr) pStatus);
  263.             
  264.             if (anErr != noErr) goto UserWantsToStop;
  265.             
  266.             /* Update the device's status */
  267.             GXReportStatus(kUserAttentionID, kPrintingStatus);
  268.         }
  269.     
  270.     /* Send out the start page HPGL2 commands to the device */
  271.     anErr = StartOfPagePlot();
  272.     if (anErr != noErr) goto CantDoStartOfPageCmnd;
  273.     
  274.     /* Pass the StartSendPage message on to the next person in the message chain */
  275.     anErr = Forward_GXStartSendPage(pageFormat);
  276.     if (anErr != noErr) goto CantSendStartPage;
  277.     
  278.     return(anErr);
  279.     
  280. /******* Cleanup *******/
  281.  
  282. CantSendStartPage:
  283. CantDoStartOfPageCmnd:
  284. UserWantsToStop:
  285. CantMakeStatusRecord:
  286. CantFlushDataPageAdvance:
  287. CantAdvanceThePage:
  288.     GXDisposeTransform((*hImageData)->devTransform);    
  289.     (*hImageData)->devTransform = nil;
  290.     
  291.     return(anErr);
  292. }
  293. /* SD_StartSendPage */
  294.  
  295.  
  296. /* ======= SD_FinishSendPage =======
  297.  
  298.     The FinishSendPage message is issued when ImagePage is getting finished rendering the current
  299.     page.  SD_FinishSendPage uses this signal to do three functions: 1) remove the device 
  300.     transformatiom so it won't inadvertantly affect the scaling, rotation, etc. the
  301.     Vector IE is doing; 2) if the paper in the plotter is to be cut, now is the time to
  302.     issue the cut command; and 3) force the pen to return to the carousel so the user can pull
  303.     out the paper.
  304. */
  305. OSErr SD_FinishSendPage(void)
  306. {
  307.  
  308.     OSErr                     anErr = noErr;
  309.     gxVectorImageDataHdl     hImageData;
  310.  
  311.      /* Deallocate the existing device transform */
  312.     hImageData = gGlobals.hImageData;
  313.     if ((*hImageData)->devTransform != nil)
  314.     {
  315.         GXDisposeTransform((*hImageData)->devTransform);
  316.         (*hImageData)->devTransform = nil;
  317.     }
  318.     
  319.     /* end of plotting */
  320.     anErr = EndOfPagePlot();
  321.     if (anErr != noErr) 
  322.         return(anErr);
  323.     
  324.     /* First make sure all pending I/O has completed so that everything prints on the current page. */
  325.     anErr = Send_GXWriteData(nil, 0);
  326.     if (anErr != noErr)
  327.         return(anErr);
  328.  
  329.  
  330.     /* Pass the FinishSendPage message on to the next person in the message chain */
  331.     anErr = Forward_GXFinishSendPage();
  332.     
  333.     return(anErr);
  334.     
  335. }
  336. /* SD_FinishSendPage */
  337.  
  338.  
  339. /* ======= SD_SetupImageData =======
  340.  
  341.     The SetupImageData message is issued to allow the driver to initialize any constant data that
  342.     is used for imaging the entire document.  SD_SetupImageData initializes fields within the 
  343.     hImageData handle so that the Vector IE knows how to image the pages given the specific
  344.     constraints of the device.  
  345. */
  346. OSErr SD_SetupImageData(            //    (out)    error code
  347.     gxVectorImageDataHdl    hImageData)    //    (in)    handle to the Vector IE imaging specific information
  348. {
  349.     
  350.     OSErr                    anErr = noErr;
  351.     gxVectorImageDataPtr    pImageData;
  352.     gxGraphicsError            stickyErr;
  353.     gxPenTableHdl            hPenTable;
  354.     gxColor                    theBkgrndColor;
  355.     gxColorSet                theColorSet;
  356.     gxPenTableEntry            *pPen;
  357.     
  358.  
  359.     gGlobals.bufferSize = 0;
  360.     
  361.     {
  362.         pImageData = *hImageData;
  363.         
  364.         pImageData->renderOptions = gxATransferMode | gxPenLessPlotter;
  365.         pImageData->devRes        = ff(1016); // HPGL/2 is 1016 dpi plotter
  366.         pImageData->devTransform    = GXNewTransform();
  367.         
  368.         /* Assign constant vector image data values */
  369.         pImageData->shapeData.shapeOptions    = 0;
  370.         pImageData->shapeData.maxPolyPoints    = 150;  // don't send a polygon with number of points more than this.
  371.         pImageData->shapeData.shapeError    = 0x00004000; // 1/4 pixel at 72 dpi
  372.         pImageData->shapeData.textSize    = ff(24);  // outline text below 24 point size
  373.         pImageData->shapeData.frameSize    = ff(1);  // fill framed shapes; do not stroke them
  374.         
  375.     }
  376.  
  377.     /* Set up the background color for the device to be white */
  378.     theBkgrndColor.space             = gxRGBSpace;
  379.     theBkgrndColor.profile             = nil;
  380.     theBkgrndColor.element.rgb.red     = 0xffff;
  381.     theBkgrndColor.element.rgb.green = 0xffff;
  382.     theBkgrndColor.element.rgb.blue     = 0xffff;
  383.     theBkgrndColor.element.component[4]      = 0; // must be initialized
  384.  
  385.      {    
  386.     /* Create a representation of the pen table */
  387.         short        numColors = 2;
  388.         gxSetColor    pSetOfColors[2];
  389.         gxSetColor    *pAColor;
  390.         
  391.         pAColor = &pSetOfColors[0];
  392.         /* black color */
  393.         pAColor->rgb.red = 0;
  394.         pAColor->rgb.green = 0;
  395.         pAColor->rgb.blue = 0;
  396.         ++pAColor;
  397.         pAColor->rgb.red = 0xffff;
  398.         pAColor->rgb.green = 0xffff;
  399.         pAColor->rgb.blue = 0xffff;
  400.         
  401.         theColorSet = GXNewColorSet(gxRGBSpace, numColors, pSetOfColors);
  402.         if (theColorSet == nil)
  403.            {
  404.            anErr = GXGetGraphicsError(&stickyErr);
  405.            goto CantMakeColorSet;
  406.            }
  407.            
  408.     /* Allocate space for the pen table we will return */
  409.     hPenTable = (gxPenTableHdl) NewHandle( sizeof(gxPenTable) + (2 * sizeof(gxPenTableEntry)));
  410.     if ((anErr = MemError()) != noErr) goto CantMakePenTable;
  411.     
  412.     (*hPenTable)->numPens = 2;
  413.     pPen = &((*hPenTable)->pens[0]);
  414.     BlockMove("\pBlack", &pPen->penName[0], 6);
  415.     pPen->penPosition = 1;
  416.     pPen->penColor.space = gxIndexedSpace;
  417.     pPen->penColor.element.indexed.index = 1; // for black
  418.     pPen->penUnits = 0; // device units i.e. 72dpi
  419.     pPen->penThickness = 0x00008000; // half a pixel at 72 dpi
  420.     
  421.     pPen = &((*hPenTable)->pens[1]);
  422.     BlockMove("\pWhite", &pPen->penName[0], 6);
  423.     pPen->penPosition = 2;
  424.     pPen->penColor.space = gxIndexedSpace;
  425.     pPen->penColor.element.indexed.index = 2; // for white
  426.     pPen->penUnits = 0; // device units i.e. 72dpi
  427.     pPen->penThickness = 0x00008000; // half an inch at 72 dpi
  428.  
  429.     pImageData = *hImageData;
  430.     
  431.     pImageData->hPenTable    = hPenTable;
  432.     GXConvertColor(&theBkgrndColor, gxIndexedSpace, theColorSet, nil);
  433.     pImageData->bgColor        = theBkgrndColor;
  434.     pImageData->clrSet        = theColorSet;
  435.     
  436.     pImageData->halftoneInfo.halftoneSpace = gxNoSpace;
  437.     pImageData->halftoneInfo.penIndexForBW = 1; // first pen
  438.     
  439.     }
  440.     
  441.     /* Remember the vector image data handle for later use during imaging */
  442.     gGlobals.hImageData = hImageData;
  443.  
  444.     return(anErr);
  445.     
  446. /******* Cleanup *******/
  447.  
  448. CantMakePenTable:
  449. CantMakeColorSet:
  450.  
  451.     GXDisposeTransform((*hImageData)->devTransform);
  452.     (*hImageData)->devTransform = nil;
  453.     return(anErr);
  454.  
  455. }
  456. /* SD_SetupImageData */
  457.  
  458.  
  459. /* ======= SD_CloseConnection =======
  460.  
  461.     The CloseConnection message is issued when the Printing Manager is closing the connection to the
  462.     plotter. SD_CloseConnection uses this opportunity to dispose of the color set that the driver
  463.     allocated and stored in the VectorImageData at SetupImageData time. 
  464. */
  465. OSErr SD_CloseConnection(void)    //    (in)    handle to the driver's globals
  466. {
  467.  
  468.     OSErr                    anErr = noErr;
  469.     gxVectorImageDataHdl      hImageData;
  470.  
  471.     hImageData = gGlobals.hImageData;
  472.  
  473.     /* Dispose of the Color Set if it was allocated */
  474.     if ((*hImageData)->clrSet != nil)
  475.     {
  476.         GXDisposeColorSet((*hImageData)->clrSet);
  477.         (*hImageData)->clrSet = nil;
  478.     }
  479.  
  480.     /* Dispose of the Pentable if it was allocated */
  481.     if ((*hImageData)->hPenTable != nil)
  482.     {
  483.         DisposHandle((Handle) (*hImageData)->hPenTable);
  484.         (*hImageData)->hPenTable = nil;
  485.     }
  486.  
  487.     /* Dispose of the Device Transform if it was allocated */
  488.     if ((*hImageData)->devTransform != nil)
  489.     {
  490.         GXDisposeTransform((*hImageData)->devTransform);
  491.         (*hImageData)->devTransform = nil;
  492.     }
  493.  
  494.     anErr = Forward_GXCloseConnection();
  495.     
  496.     return(anErr);
  497.     
  498. }
  499. /* SD_CloseConnection */
  500.  
  501.  
  502. /* ========================= VECTOR SPECIFIC MESSAGE OVERRIDE ROUTINES ========================= */
  503.  
  504. /* ======= SD_PackageData =======
  505.  
  506.     The PackageData message is issued by the Vector IE to signal that the specific driver should
  507.     package the Graphics shape, shapeToDraw, in HPGL commands so it will be drawn.  The routine should
  508.     only ever receive line, rectangle, and non-filled polygon shapes from the Vector IE.  Anything
  509.     else is an error.  The penIndex specifies which pen in the carousel to use for drawing.  If
  510.     it's different than the last pen used to draw, HPGL commands are generated to select the target
  511.     pen.
  512. */
  513. OSErr SD_PackageData(                    //    (out)    error code
  514.     gxShape                shapeToDraw,    //    (in)    Graphics shape to be drawn
  515.     long                penIndex)        //    (in)    index in the carousel of the pen to use for drawing
  516. {
  517.    #pragma unused (penIndex)
  518.  
  519.     OSErr                    anErr = noErr;
  520.     gxShapeAttribute        theAttributes;
  521.     gxVectorImageDataHdl      hImageData;
  522.     gxMapping                theMapping;
  523.     fixed                    spenWidth;
  524.     gxColor                    clr;
  525.     short                    n;
  526.     char                    theStr[256];
  527.     
  528.     hImageData = gGlobals.hImageData;
  529.     
  530.     /* Create a temporary mapping that will scale the shape's points to the resolution of the device */
  531.     {
  532.         fixed        scaleFactor;
  533.  
  534.         scaleFactor = FixDiv((*hImageData)->devRes, ff(72));
  535.         
  536.          ResetMapping(&theMapping);
  537.          ScaleMapping(&theMapping, scaleFactor, scaleFactor, 0, 0);
  538.     }
  539.     
  540.     /* Make sure the shape is accessible to us by setting the directShape attribute.  This */
  541.     /* ensures we can access the shape's structure without it disappearing on us. */
  542.     theAttributes = GXGetShapeAttributes(shapeToDraw);
  543.     GXSetShapeAttributes(shapeToDraw, theAttributes | gxDirectShape);
  544.     
  545.     /* Lock the shape so it doesn't move while we access its structure */
  546.     GXLockShape(shapeToDraw);
  547.  
  548.     /* set the pen thickness and the pen color */
  549.      spenWidth = GXGetShapePen(shapeToDraw);
  550.      if (spenWidth != 0)
  551.         /* convert shape thickness in mm */
  552.         spenWidth = FixedDivide(spenWidth, ff(40)); // 1016 dpi ==> 40 plotterpoints per mm.
  553.      else
  554.         spenWidth = FixedDivide(ff(25), ff(1000));
  555.      if (gGlobals.penWidth != spenWidth)
  556.         {
  557.         // DebugStr("\p setting pen width.. ");
  558.           GetIndString(theStr, kHPXLCmndStringsID, kSetPenWidthIdx);
  559.         theStr[theStr[0]+1] = 0;
  560.           n = sprintf(gGlobals.tempBuffer, &theStr[1], Fix2X(spenWidth));
  561.           anErr = MyDumpBuffer( n);
  562.  
  563.         if (anErr != noErr)
  564.            return(anErr);
  565.         gGlobals.penWidth = spenWidth;
  566.         }
  567.  
  568.      GXGetShapeColor(shapeToDraw, &clr);
  569.       GetIndString(theStr, kHPXLCmndStringsID, kSetPenColorIdx);
  570.     theStr[theStr[0]+1] = 0;
  571.       n = sprintf(gGlobals.tempBuffer, &theStr[1], 1, clr.element.rgb.red >> 1, 
  572.                                clr.element.rgb.green >> 1, 
  573.                               clr.element.rgb.blue >> 1);
  574.       anErr = MyDumpBuffer( n);
  575.     if (anErr != noErr)
  576.           return(anErr);
  577.     
  578.     switch ( GXGetShapeType(shapeToDraw) )
  579.     {
  580.         case gxLineType:
  581.             anErr = PlotLine(shapeToDraw, theMapping);
  582.             if (anErr != noErr) goto CantSendPlotLineCmnd;
  583.             break;
  584.             
  585.         case gxRectangleType:
  586.             anErr = PlotRectangle(shapeToDraw, theMapping);
  587.             if (anErr != noErr) goto CantSendPlotRectCmnd;
  588.             break;
  589.             
  590.         case gxPolygonType:
  591.             anErr = PlotPolygon(shapeToDraw, theMapping);
  592.             if (anErr != noErr) goto CantSendPlotPolyCmnd;
  593.             break;
  594.             
  595.         default:
  596.             break;// Not expecting any other shape types from the Vector IE
  597.     }
  598.  
  599.     /* Unlock the shape so it can move again */
  600.     GXUnlockShape(shapeToDraw);
  601.     
  602.     /* Restore the shape's attributes */
  603.     GXSetShapeAttributes(shapeToDraw, theAttributes);
  604.     
  605.     return(anErr);
  606.     
  607. /******* Cleanup *******/
  608.  
  609. CantSendPlotPolyCmnd:
  610. CantSendPlotRectCmnd:
  611. CantSendPlotLineCmnd:
  612. CantSendSwitchPensCmnd:
  613.     GXUnlockShape(shapeToDraw);
  614.     GXSetShapeAttributes(shapeToDraw, theAttributes);
  615.  
  616.     return(anErr);
  617. }
  618. /* SD_PackageData */
  619.  
  620. /* following stubs are to avoid errors in linking the driver. sprintf is allowed only for
  621. MPW tools and stand alone apps */
  622. size_t fwrite(const void*, size_t, size_t, FILE*)
  623. {
  624. DebugStr("\p in fwrite");
  625. return(0);
  626. }
  627.  
  628. _flsbuf()
  629. {
  630. DebugStr("\p in _flsbuf");
  631. }
  632.  
  633.